﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using Common;
using Common.Dao;
using Common.Model;
using log4net;

namespace StockIndex.service
{
    public class TdxDailyKLineService
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(TdxDailyKLineService));

        //填充本地所有的,这个用于填补数据
        public static void FullTotalStockDailyKLines()
        {
            var directoryPath = $@"{Config.TdxPath}/vipdoc";
            var szDirectoryPath = $@"{directoryPath}/sz/lday";
            var shDirectoryPath = $@"{directoryPath}/sh/lday";
            var szDailyKlines = ParseTatalKLines(szDirectoryPath);
            var shDailyKLines = ParseTatalKLines(shDirectoryPath);
            var dailyKLines = new List<DailyKLine>();
            dailyKLines.AddRange(szDailyKlines);
            dailyKLines.AddRange(shDailyKLines);
            DailyKLineDao.UpdateOrAddDailyKLine(dailyKLines);
        }

//        public static void Main(string[] args)
//        {
////            FullTotalStockDailyKLines();
//            FullLastestDailyKLines();
//        }

        private static List<DailyKLine> ParseTatalKLines(string directoryPath)
        {
            DirectoryInfo szDirectoryInfo = new DirectoryInfo(directoryPath);
            var dailyKLines = new List<DailyKLine>();
            foreach (FileInfo fileInfo in szDirectoryInfo.GetFiles("*.day"))
            {
                try
                {
                    var file = File.Open(fileInfo.FullName, FileMode.Open, FileAccess.Read,
                        FileShare.ReadWrite);
                    var market = fileInfo.Name.Substring(0, 2).ToUpper();

                    var code = fileInfo.Name.Substring(2, 6);
                    var stockCode = $"{code}.{market}";
                    //只放A股的数据
                    if (code.StartsWith("0") || code.StartsWith("3") || code.StartsWith("6"))
                    {
                        using (var reader = new BinaryReader(file))
                        {
                            while (reader.BaseStream.Position < reader.BaseStream.Length)
                            {
                                var dailyKLine = GetFullValue(reader, stockCode);
                                dailyKLines.Add(dailyKLine);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Error("error", e);
                }
            }

            Log.Info($"需要插入日线数据：{dailyKLines.Count}条");
            return dailyKLines;
        }

        //填充最新日期
        public static void FullLastestDailyKLines()
        {
            var directoryPath = $@"{Config.TdxPath}/vipdoc";
            var szDirectoryPath = $@"{directoryPath}/sz/lday";
            var shDirectoryPath = $@"{directoryPath}/sh/lday";
            var szDailyKlines = ParseLastestKLines(szDirectoryPath);
            var shDailyKLines = ParseLastestKLines(shDirectoryPath);
            var dailyKLines = new List<DailyKLine>();
            dailyKLines.AddRange(szDailyKlines);
            dailyKLines.AddRange(shDailyKLines);
            DailyKLineDao.UpdateOrAddDailyKLine(dailyKLines);
        }

        private static List<DailyKLine> ParseLastestKLines(string directoryPath)
        {
            DirectoryInfo szDirectoryInfo = new DirectoryInfo(directoryPath);
            var dailyKLines = new List<DailyKLine>();
            foreach (FileInfo fileInfo in szDirectoryInfo.GetFiles("*.day"))
            {
                try
                {
                    var file = File.Open(fileInfo.FullName, FileMode.Open, FileAccess.Read,
                        FileShare.ReadWrite);
                    var market = fileInfo.Name.Substring(0, 2).ToUpper();

                    var code = fileInfo.Name.Substring(2, 6);
                    var stockCode = $"{code}.{market}";
                    //只放A股的数据
                    if (code.StartsWith("0") || code.StartsWith("3") || code.StartsWith("6"))
                    {
                        using (var reader = new BinaryReader(file))
                        {
                            reader.BaseStream.Position = reader.BaseStream.Length - 32; //移动到最后一条数据
                            while (reader.BaseStream.Position < reader.BaseStream.Length)
                            {
                                var dailyKLine = GetFullValue(reader, stockCode);
                                dailyKLines.Add(dailyKLine);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Error("error", e);
                }
            }

            Log.Info($"需要增量插入日线数据：{dailyKLines.Count}条");
            return dailyKLines;
        }

        /// <summary>
        /// 填充模型数据
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="stockCode"></param>
        /// <returns></returns>
        private static DailyKLine GetFullValue(BinaryReader reader, string stockCode)
        {
            var date = reader.ReadUInt32();
            var openPrice = reader.ReadUInt32();
            var higestPrice = reader.ReadUInt32();
            var lowestPrice = reader.ReadUInt32();
            var closePrice = reader.ReadUInt32();
            var tradingAmount = reader.ReadSingle(); //
            var tradingVolume = reader.ReadUInt32(); //单位：手
            var nouse = reader.ReadUInt32(); //这个还没有用
            DailyKLine kLine = new DailyKLine
            {
                UpdateTime = DateTime.ParseExact(date.ToString(), "yyyyMMdd",
                    CultureInfo.CurrentCulture),
                OpenPrice = (decimal) openPrice / (decimal) 100,
                ClosePrice = (decimal) closePrice / (decimal) 100,
                StockCode = stockCode,
                Volume = tradingVolume
            };
            return kLine;
        }
    }
}